package com.wang.lottery.domain.rule.service.engine;

import com.wang.lottery.common.Constants;
import com.wang.lottery.domain.rule.model.aggregates.TreeRuleRich;
import com.wang.lottery.domain.rule.model.req.DecisionMatterReq;
import com.wang.lottery.domain.rule.model.vo.TreeNodeVO;
import com.wang.lottery.domain.rule.model.vo.TreeRootVO;
import com.wang.lottery.domain.rule.service.logic.LogicFilter;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;

/**
 * @author wjh
 * @create 2023-11-11 17:48
 * 规则引擎基础类
 */
@Slf4j
public abstract class EngineBase extends EngineConfig implements EngineFilter{
    

    /**
     * 这个方法根据用户信息，比如性别年龄返回和用户匹配的叶子节点信息
     * @param treeRuleRich 规则树聚合
     * @param matter 决策信息
     * @return 匹配的叶子节点信息
     */
    protected TreeNodeVO engineDecisionMaker(TreeRuleRich treeRuleRich, DecisionMatterReq matter) {
        TreeRootVO treeRoot = treeRuleRich.getTreeRoot();
        Map<Long, TreeNodeVO> treeNodeMap = treeRuleRich.getTreeNodeMap();
        Long treeRootNodeId = treeRoot.getTreeRootNodeId();
        //获取根节点
        TreeNodeVO treeNodeVO = treeNodeMap.get(treeRootNodeId);
        //从根节点开始遍历，每个节点都存有规则key，根据规则key可以拿到对应的规则过滤器实现类
        while (Constants.NodeType.STEM.equals(treeNodeVO.getNodeType())) {
            if (treeNodeVO.getRuleTreeNodeLineList().size() == 0) {
                break;
            }
            LogicFilter logicFilter = super.filterMap.get(treeNodeVO.getRuleKey());
            //获取决策值
            String matterValue = logicFilter.matterValue(matter);
            //根据决策值获取下一个节点
            Long nextNodeId = logicFilter.filter(matterValue, treeNodeVO.getRuleTreeNodeLineList());
            //treeNodeVO赋值为下一个节点，直到treeNodeVO为叶子节点while循环就会跳出
            treeNodeVO = treeNodeMap.get(nextNodeId);
            //打印info日志
            log.info("决策树引擎=>{} userId：{} treeId：{} treeNode：{} ruleKey：{} matterValue：{}", treeRoot.getTreeName(), matter.getuId(), matter.getTreeId(), treeNodeVO.getId(), treeNodeVO.getRuleKey(), matterValue);
        }
        return treeNodeVO;
    }
    
}
